package autotd.server;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintStream;

public class Sanitizer implements NetworkProtocol {
	public static String nextNonEmptyLine(BufferedReader input) throws Exception {
		String line = input.readLine();
		while ((line != null) && (line.length() == 0)) {
			line = input.readLine();
		}
		return line;
	}


	public static void sanitize(File infile, File outfile) throws Exception {
		BufferedReader input = new BufferedReader(new FileReader(infile));
		PrintStream output = new PrintStream(outfile);

		String nextLine = nextNonEmptyLine(input);
		while (nextLine != null) {
			String[] tokens = nextLine.split(" ");
			if (tokens[0].equals(CMD_PLACE_TOWER)) {
				if (checkPlaceTower(nextLine)) {
					output.println(nextLine);
				}
			} else if (tokens[0].equals(CMD_FIRE_TOWER)) {
				if (checkFireTower(nextLine)) {
					output.println(nextLine);
				}
			} else if(tokens[0].equals(CMD_TICK)) {
				if (checkTick(nextLine)) {
					output.println(nextLine);
				}
			} else {
				System.out.println("Dropping unrecognised line " + nextLine);
			}
			nextLine = nextNonEmptyLine(input);
		}
		output.flush();
		output.close();
	}


	public static boolean isInteger(String token) {
		try {
			Integer.parseInt(token);
			return true;
		} catch(NumberFormatException nfe) {
			return false;
		}
	}

	public static boolean isSuspicious(String token) {
		for (int pos = 0; pos < token.length(); pos++) {
			char c = token.charAt(pos);
			boolean ok = ((c >= 'a') && (c <= 'z'))
					  || ((c >= 'A') && (c <= 'Z'))
					  || ((c >= '0') && (c <= '9'))
					  || (c == '-') || (c == '_')
					;
			if (!ok) {
				return true;
			}
		}
		return false;
	}



	public static boolean checkTick(String line) {
		String[] tokens = line.split(" ");
		if (tokens.length != 2) {
			System.out.println("Tick should have exactly 2 tokens: " + line);
			return false;
		} else if (!isInteger(tokens[1])) {
			System.out.println("Badly formatted tick count: " + line);
			return false;
		}
		return true;
	}


	public static boolean checkPlaceTower(String line) {
		String[] tokens = line.split(" ");
		if (tokens.length != 4) {
			System.out.println("Place tower should have exactly 4 tokens: " + line);
			return false;
		} else if (!isInteger(tokens[1])) {
			System.out.println("Badly formatted x-coord: " + line);
			return false;
		} else if (!isInteger(tokens[2])) {
			System.out.println("Badly formatted y-coord: " + line);
			return false;
		} else if (isSuspicious(tokens[3])) {
			System.out.println("Suspicious tower type: " + line);
			return false;
		}
		return true;
	}


	public static boolean checkFireTower(String line) {
		String[] tokens = line.split(" ");
		if (tokens.length != 4) {
			System.out.println("Fire tower should have exactly 4 tokens: " + line);
			return false;
		} else if (!isInteger(tokens[1])) {
			System.out.println("Badly formatted x-coord: " + line);
			return false;
		} else if (!isInteger(tokens[2])) {
			System.out.println("Badly formatted y-coord: " + line);
			return false;
		} else if (!isInteger(tokens[3])) {
			System.out.println("Badly formatted tower-id: " + line);
			return false;
		}
		return true;
	}
}